package stone926.mods.more_enchantments.util;

import net.minecraft.advancement.criterion.Criteria;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Bucketable;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.mob.Hoglin;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsage;
import net.minecraft.item.Items;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import stone926.mods.more_enchantments.MoreEnchantmentsMod;

import java.util.Optional;

public class InterfaceCopy {

  public static <T extends LivingEntity & Bucketable> Optional<ActionResult> tryBucket(PlayerEntity player, Hand hand, T entity) {
    ItemStack itemStack = player.getStackInHand(hand);
    int pourLvl = EnchantmentHelper.getLevel(MoreEnchantmentsMod.POUR, itemStack);
    if (pourLvl <= 0) return Optional.empty();
    if (itemStack.getItem() == Items.WATER_BUCKET && entity.isAlive()) {
      entity.playSound(entity.getBucketedSound(), 1.0F, 1.0F);
      ItemStack itemStack2 = entity.getBucketItem();
      entity.copyDataToStack(itemStack2);
      ItemStack itemStack3 = ItemUsage.exchangeStack(itemStack, player, itemStack2, false);
      itemStack3.addEnchantment(MoreEnchantmentsMod.POUR, pourLvl);
      player.setStackInHand(hand, itemStack3);
      World world = entity.world;
      if (!world.isClient) {
        Criteria.FILLED_BUCKET.trigger((ServerPlayerEntity) player, itemStack2);
      }
      entity.discard();
      return Optional.of(ActionResult.success(world.isClient));
    } else {
      return Optional.empty();
    }
  }

  public static boolean tryAttack(LivingEntity attacker, LivingEntity target, double knockbackChance) {
    float f = (float) attacker.getAttributeValue(EntityAttributes.GENERIC_ATTACK_DAMAGE);
    float h;
    if (!attacker.isBaby() && (int) f > 0) {
      h = f / 2.0F + (float) attacker.world.random.nextInt((int) f);
    } else {
      h = f;
    }

    boolean bl = target.damage(DamageSource.mob(attacker), h);
    if (bl) {
      attacker.applyDamageEffects(attacker, target);
      if (!attacker.isBaby()) {
        RandomUtil.runIfPossible(knockbackChance, attacker.getRandom(), () -> Hoglin.knockback(attacker, target));
      }
    }

    return bl;
  }

}
